package com.simulation.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.simulation.model.SimulationConfig;
import com.simulation.model.SimulationTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Optional;

@Service
public class ConfigurationService  implements ApplicationRunner {
    private static final Logger logger = LoggerFactory.getLogger(ConfigurationService.class);
    
    @Value("${simulation.config.file:simulation-config.json}")
    private String configFilePath;
    
    private SimulationConfig config;
    private final ObjectMapper objectMapper = new ObjectMapper();


    @Override
    public void run(ApplicationArguments args) throws Exception {
        loadConfiguration();
    }

//    @PostConstruct
    public void loadConfiguration() {
        try {
            File configFile = new File(configFilePath);
            if (!configFile.exists()) {
                logger.warn("Configuration file not found: {}, using default configuration", configFilePath);
                createDefaultConfiguration();
                return;
            }

            config = objectMapper.readValue(configFile, SimulationConfig.class);
            logger.info("Configuration loaded successfully from: {}", configFilePath);
            
            // 验证配置
            validateConfiguration();
            
        } catch (IOException e) {
            logger.error("Failed to load configuration from: {}", configFilePath, e);
            createDefaultConfiguration();
        }
    }

    /**
     * 获取配置对象
     */
    public SimulationConfig getConfig() {
        return config;
    }

    /**
     * 获取所有模拟模板
     */
    public List<SimulationTemplate> getSimulationTemplates() {
        return config != null ? config.getSimulationTemplates() : List.of();
    }

    /**
     * 根据ID获取模拟模板
     */
    public Optional<SimulationTemplate> getTemplateById(String templateId) {
        if (config == null || config.getSimulationTemplates() == null) {
            return Optional.empty();
        }
        
        return config.getSimulationTemplates().stream()
            .filter(template -> templateId.equals(template.getTemplateId()))
            .findFirst();
    }

    /**
     * 添加新的模拟模板
     */
    public void addTemplate(SimulationTemplate template) {
        if (config != null && config.getSimulationTemplates() != null) {
            config.getSimulationTemplates().add(template);
            saveConfiguration();
            logger.info("Added new template: {}", template.getTemplateId());
        }
    }

    /**
     * 更新模拟模板
     */
    public boolean updateTemplate(String templateId, SimulationTemplate updatedTemplate) {
        if (config == null || config.getSimulationTemplates() == null) {
            return false;
        }

        for (int i = 0; i < config.getSimulationTemplates().size(); i++) {
            SimulationTemplate template = config.getSimulationTemplates().get(i);
            if (templateId.equals(template.getTemplateId())) {
                config.getSimulationTemplates().set(i, updatedTemplate);
                saveConfiguration();
                logger.info("Updated template: {}", templateId);
                return true;
            }
        }
        
        logger.warn("Template not found for update: {}", templateId);
        return false;
    }

    /**
     * 删除模拟模板
     */
    public boolean deleteTemplate(String templateId) {
        if (config == null || config.getSimulationTemplates() == null) {
            return false;
        }

        boolean removed = config.getSimulationTemplates().removeIf(
            template -> templateId.equals(template.getTemplateId())
        );
        
        if (removed) {
            saveConfiguration();
            logger.info("Deleted template: {}", templateId);
        } else {
            logger.warn("Template not found for deletion: {}", templateId);
        }
        
        return removed;
    }

    /**
     * 保存配置到文件
     */
    public void saveConfiguration() {
        try {
            File configFile = new File(configFilePath);
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(configFile, config);
            logger.debug("Configuration saved to: {}", configFilePath);
        } catch (IOException e) {
            logger.error("Failed to save configuration to: {}", configFilePath, e);
        }
    }

    /**
     * 重新加载配置
     */
    public void reloadConfiguration() {
        logger.info("Reloading configuration...");
        loadConfiguration();
    }

    /**
     * 验证配置
     */
    private void validateConfiguration() {
        if (config == null) {
            throw new IllegalStateException("Configuration is null");
        }

        if (config.getOpcuaServer() == null) {
            throw new IllegalStateException("OPC UA server configuration is missing");
        }

        if (config.getSimulationTemplates() == null || config.getSimulationTemplates().isEmpty()) {
            logger.warn("No simulation templates configured");
        }

        // 验证模板
        if (config.getSimulationTemplates() != null) {
            for (SimulationTemplate template : config.getSimulationTemplates()) {
                validateTemplate(template);
            }
        }

        logger.info("Configuration validation completed successfully");
    }

    /**
     * 验证模板
     */
    private void validateTemplate(SimulationTemplate template) {
        if (template.getTemplateId() == null || template.getTemplateId().trim().isEmpty()) {
            throw new IllegalStateException("Template ID is required");
        }

        if (template.getDataPoints() == null || template.getDataPoints().isEmpty()) {
            throw new IllegalStateException("Template must have at least one data point: " + template.getTemplateId());
        }

        // 验证数据点
        template.getDataPoints().forEach(dataPoint -> {
            if (dataPoint.getPointName() == null || dataPoint.getPointName().trim().isEmpty()) {
                throw new IllegalStateException("Data point name is required in template: " + template.getTemplateId());
            }
            
            if (dataPoint.getDataType() == null || dataPoint.getDataType().trim().isEmpty()) {
                throw new IllegalStateException("Data point type is required: " + dataPoint.getPointName());
            }
        });
    }

    /**
     * 创建默认配置
     */
    private void createDefaultConfiguration() {
        config = new SimulationConfig();
        
        // 创建默认OPC UA服务器配置
        SimulationConfig.OpcuaServerConfig opcuaConfig = new SimulationConfig.OpcuaServerConfig();
        opcuaConfig.setEndpoint("opc.tcp://localhost:4840");
        opcuaConfig.setNamespaceUri("urn:simulation:server");
        opcuaConfig.setRootPath("Simulation");
        config.setOpcuaServer(opcuaConfig);
        
        // 创建默认全局设置
        SimulationConfig.GlobalSettings globalSettings = new SimulationConfig.GlobalSettings();
        globalSettings.setDefaultCycle(1000);
        globalSettings.setMaxConcurrentTasks(100);
        globalSettings.setLogLevel("INFO");
        globalSettings.setEnableMetrics(true);
        config.setGlobalSettings(globalSettings);
        
        config.setSimulationTemplates(List.of());
        
        logger.info("Created default configuration");
    }

    /**
     * 获取OPC UA服务器配置
     */
    public SimulationConfig.OpcuaServerConfig getOpcuaServerConfig() {
        return config != null ? config.getOpcuaServer() : null;
    }

    /**
     * 获取全局设置
     */
    public SimulationConfig.GlobalSettings getGlobalSettings() {
        return config != null ? config.getGlobalSettings() : null;
    }

}